package com.clerkq.CoverFlow
{
	
	import com.content.model.OnlineRes.OnlineResHomeVO;
	
	import flash.display.*;
	import flash.events.*;
	import flash.geom.*;
	import flash.net.*;
	import flash.utils.*;
	
	public class Cover extends Sprite {
	
		private var _src:String;
//		private var _caption:String;
//		private var _data:XML;
		private var _vo:OnlineResHomeVO;
		private var _loader:Loader;
		private var _reflection:Bitmap;
		private var _backgroundColor:uint;
		
		private var _startX:Number;
		private var _endX:Number;
		private var _startRotationY:Number;
		private var _endRotationY:Number;
		private var _startZ:Number;
		private var _endZ:Number;
		private var _coverFlowParent:CoverFlow;
		private var _centerMargin:Number;
		private var _distanceFromCenter:Number;
		
//		public function Cover(caption:String, data:XML, backgroundColor:Number) {
		public function Cover(vo:OnlineResHomeVO, backgroundColor:Number) {
			_vo = vo;
			_backgroundColor = backgroundColor;
			this.doubleClickEnabled = true;
			this.mouseChildren = false;
		}
		
		public function get VO():OnlineResHomeVO {
			return _vo;
		}

		public function set backgroundColor(num:Number):void {
			_backgroundColor = num;
			drawReflection();
		}
		public function get backgroundColor():Number {
			return _backgroundColor;
		}
		
		public function set dropOff(value:Number):void {
			value = Math.max(0, Math.min(1, value));
			
			var r:uint = _backgroundColor >> 16;
			var g:uint = _backgroundColor >> 8 & 0xFF;
			var b:uint = _backgroundColor & 0xFF;
			
			var multiplier:Number = 1 - value;
			
			var color:ColorTransform = new ColorTransform(multiplier, multiplier, multiplier, 1, r * value, g * value, b * value, 0);
			this.transform.colorTransform = color;
		}
		
		internal function set endX(n:Number):void {
			_startX = this.x;
			_endX = n;
		}
		internal function set endRotationY(n:Number):void {
			_startRotationY = this.rotationY;
			_endRotationY = n;
		}
		internal function set endZ(n:Number):void {
			_startZ = this.z;
			_endZ = n;
		}
		
		public function load(src:String):void {
			_src = src;
			_loader = new Loader();
			_loader.contentLoaderInfo.addEventListener(ProgressEvent.PROGRESS, onLoadProgress);
			_loader.contentLoaderInfo.addEventListener(Event.COMPLETE, onLoadComplete);
			_loader.contentLoaderInfo.addEventListener(IOErrorEvent.IO_ERROR, onLoadError);
			addChild(_loader);
			_loader.load(new URLRequest(_src));
		}
		
		internal function updateTween(elapsedTime:Number, duration:Number):void {
			this.x         = ExponentialEaseOut(elapsedTime, _startX, _endX - _startX, duration);
			this.rotationY = ExponentialEaseOut(elapsedTime, _startRotationY, _endRotationY - _startRotationY, duration);
			this.z         = ExponentialEaseOut(elapsedTime, _startZ, _endZ - _startZ, duration);
			
			if (!_coverFlowParent) _coverFlowParent = this.parent.parent as CoverFlow;
			
			_distanceFromCenter = Math.abs(this.x - (_coverFlowParent.width / 2));
			_centerMargin = _coverFlowParent.centerMargin;
			if (_distanceFromCenter < _centerMargin) {
				this.dropOff = .1 * _distanceFromCenter / _centerMargin;
			} else {
				this.dropOff = .1 + ((_distanceFromCenter - _centerMargin) / _coverFlowParent.horizontalSpacing) * .1;
			}
			
		}
		
		/*
		TERMS OF USE - EASING EQUATIONS

		Open source under the BSD License. 

		Copyright © 2001 Robert Penner
		All rights reserved.

		Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:

		Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
		Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
		Neither the name of the author nor the names of contributors may be used to endorse or promote products derived from this software without specific prior written permission.
		THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
		*/
		private static function ExponentialEaseOut(t:Number, b:Number, c:Number, d:Number):Number {
			return (t==d) ? b+c : c * (-Math.pow(2, -10 * t/d) + 1) + b;
		}
		
		private function onLoadProgress(e:ProgressEvent):void {
			dispatchEvent(e);
		}

		private function onLoadComplete(e:Event):void {
			
			_loader.contentLoaderInfo.removeEventListener(ProgressEvent.PROGRESS, onLoadProgress);
			_loader.contentLoaderInfo.removeEventListener(Event.COMPLETE, onLoadComplete);
			_loader.contentLoaderInfo.removeEventListener(IOErrorEvent.IO_ERROR, onLoadError);
			
			_loader.x = -Math.round(_loader.width / 2);
			_loader.y = -_loader.height;
//			drawReflection();
			dispatchEvent(e);
		}

		private function drawReflection():void {
			if (_loader.width == 0 || _loader.height == 0) {
				return;
			}
			var clone:BitmapData = new BitmapData(_loader.width, _loader.height, false, 0x000000);
			var flip:Matrix = new Matrix();
			flip.scale(1, -1);
			flip.translate(0, _loader.height);			
			clone.draw(_loader, flip);
			
			_reflection = new Bitmap(clone);
			addChild(_reflection);
			_reflection.x = _loader.x;
			
			var gradient:Shape = new Shape();
			var gradientMatrix:Matrix = new Matrix();
			gradientMatrix.createGradientBox(_reflection.width, _reflection.height, Math.PI / 2); 
			var gradientFill:GraphicsGradientFill = new GraphicsGradientFill(GradientType.LINEAR, [_backgroundColor, _backgroundColor], [.5, 1], [0, 255], gradientMatrix);
			var gradientRect:GraphicsPath = new GraphicsPath();
			gradientRect.moveTo(0, 0);
			gradientRect.lineTo(_reflection.width, 0);
			gradientRect.lineTo(_reflection.width, _reflection.height);
			gradientRect.lineTo(0, _reflection.height);
			gradientRect.lineTo(0, 0);
			var graphicsData:Vector.<IGraphicsData> = new Vector.<IGraphicsData>();
			graphicsData.push(gradientFill, gradientRect);
			gradient.graphics.drawGraphicsData(graphicsData);

			_reflection.bitmapData.draw(gradient);
		}
		
		private function onLoadError(e:IOErrorEvent):void {
			trace("error: " + e.text)
		}
		
	}

}
